package Server

import (
	"fmt"

	"github.com/TarsCloud/TarsGo/tars"
	"github.com/TarsCloud/TarsGo/tars/util/conf"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/util/gconv"
	hypernexusclient "github.com/wzh200x/hyperNexus/hyperNexusClient"
	hypernexusnats "github.com/wzh200x/hyperNexus/hyperNexusNats"
	"github.com/wzh200x/webServer/config"
	"github.com/wzh200x/webServer/middleware/response"
	"github.com/wzh200x/webServer/middleware/signature"

	// 导入Web服务器协议包
	"github.com/wzh200x/hyperNexus/hyperNexusProtocol/webServerProtocol"
)

// WebServer 定义Web服务器结构体
type WebServer struct {
	// 可以在这里添加需要的服务器组件
	DbAgentServerClient   *hypernexusclient.DbAgentServerClient
	CacheServerClient     *hypernexusclient.CacheServerClient
	InterfaceServerClient *hypernexusclient.InterfaceServerClient
	//
	RegisterHandleFunc func(ginEngine *gin.Engine)
	//
	NatsClientIns *hypernexusnats.NatsClient
	sConf         *conf.Conf
}

// ServerApp 是全局服务器实例
var ServerApp = &WebServer{}

// Init 初始化服务器
func (ws *WebServer) Init(comm *tars.Communicator, sConf *conf.Conf) error {
	ws.sConf = sConf
	// 初始化tars
	ws.RegisterTarsObj()

	// 初始化DbAgentServerClient
	ws.DbAgentServerClient = hypernexusclient.NewDbAgentServerClient()
	err := ws.DbAgentServerClient.Init(comm)
	if err != nil {
		tars.GetLogger("").Errorf("Failed to initialize DbAgentServerClient: %v", err)
		return err
	}

	// 初始化CacheServerClient
	ws.CacheServerClient = hypernexusclient.NewCacheServerClient()
	err = ws.CacheServerClient.Init(comm)
	if err != nil {
		tars.GetLogger("").Errorf("Failed to initialize CacheServerClient: %v", err)
		return err
	}

	// 初始化InterfaceServerClient
	ws.InterfaceServerClient = hypernexusclient.NewInterfaceServerClient()
	err = ws.InterfaceServerClient.Init(comm)
	if err != nil {
		tars.GetLogger("").Errorf("Failed to initialize InterfaceServerClient: %v", err)
		return err
	}

	// 初始化平台配置
	config.InitPlatformConfig(sConf)
	tars.GetLogger("").Infof("Platform configurations initialized successfully")

	// 初始化NATS客户端
	ws.NatsClientIns = hypernexusnats.NewNatsClient()
	err = ws.NatsClientIns.Init(comm, sConf)
	if err != nil {
		tars.GetLogger("").Errorf("Failed to initialize NatsClientIns: %v", err)
		return err
	}

	tars.GetLogger("").Infof("WebServer initialized successfully")
	return nil
}

func (ws *WebServer) SetHandleRegisterFunc(f func(ginEngine *gin.Engine)) {
	ws.RegisterHandleFunc = f
}

// InitFinish 完成初始化后的操作
func (ws *WebServer) InitFinish() error {
	go func() {
		ws.StartGinServer()
	}()
	return nil
}

// Info 返回服务器信息
func (ws *WebServer) Info() string {
	return fmt.Sprintf(`server: %s version: %s`, "webServer", "0.0.1")
}

// Name 返回服务器名称
func (ws *WebServer) Name() string {
	return "webServer"
}

func (ws *WebServer) Stop() error {
	return nil
}

// RegisterTarsObj 注册Tars对象
func (ws *WebServer) RegisterTarsObj() {
	// Get server config
	cfg := tars.GetServerConfig()
	// New servant imp
	imp := new(WebServerOperateImp)
	app := new(webServerProtocol.WebServer)
	// Register Servant
	app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".WebServerOperateObj")
}

func (ws *WebServer) StartGinServer() {
	// 启动Gin服务器
	// ...
	// Get server config
	httpPort := ws.sConf.GetStringWithDef("/server/http<port>", "8080")
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()

	// 读取签名验证配置
	signEnable := ws.sConf.GetBoolWithDef("/server/signature<enable>", true)
	signSecretKey := ws.sConf.GetStringWithDef("/server/signature<secretKey>", "hyperNexus_secret_key")
	signExpireTime := ws.sConf.GetInt32WithDef("/server/signature<expireTime>", 10)
	signWhitelist := ws.sConf.GetDomain("/server/signature/whitelist")

	// 设置签名验证配置
	signConfig := signature.SignatureConfig{
		Enable:     signEnable,
		SecretKey:  signSecretKey,
		ExpireTime: gconv.Int64(signExpireTime),
		Whitelist:  signWhitelist,
	}
	signature.SetSignatureConfig(signConfig)
	// 自定义CORS配置,允许跨域
	r.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length, Authorization, Content-Type")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}
		c.Next()
	})
	// 应用统一响应中间件
	r.Use(response.ResponseMiddleware())
	// 应用签名验证中间件
	r.Use(signature.SignatureMiddleware())

	ws.RegisterHandleFunc(r)
	r.Run(":" + httpPort)
}
